package cn.est.service.impl;

import cn.est.config.OssConfig;
import cn.est.constants.Constants;
import cn.est.exceptions.FileException;
import cn.est.service.FileService;
import cn.est.utils.UUIDUtils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import org.apache.tomcat.util.bcel.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@Service
public class FileServiceImpl implements FileService {

    private static final String[] image_type=new String[]{"png","gif","jpg","xlsx"};

    @Autowired
    private OSS ossClient;   //对oss服务器进行操作的客户端

    @Autowired
    private OssConfig ossConfig; //配置类读取类



    @Override
    public String upload(MultipartFile multipartFile) throws FileException {

       //1.判断文件的类型
        boolean isLegal=false;  //默认不符合文件上传条件
        //2.获取文件的原名
        String orginfileName=  multipartFile.getOriginalFilename();
        for (String type :image_type){
           if(StringUtils.endsWithIgnoreCase(orginfileName,type)) {
               isLegal=true;   //匹配中
               break;
           };
        }

        if(!isLegal){
            throw   new FileException("文件上传格式不正确");
        }

        String  fileType=orginfileName.substring(orginfileName.lastIndexOf("."));

       //3.创建一个新的文件名，保证唯一性
        String newFileName = UUIDUtils.getUUID32().toString()+fileType;

       //4.构建一个日期的路劲，比如说oss目标文件夹  2021/4/22文件名

        String filePath=new SimpleDateFormat("yyyy/MM/dd").format(new Date());

        String uploadImageUrl = Constants.OSS.ESTBASEURL+"/"+filePath+"/"+newFileName;

        //5.设置文件上传的属性
        // 创建上传文件的元信息，可以通过文件元信息设置HTTP header。
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentType("image/jpg");

        //7.文件上传到阿里oss服务器
        InputStream inputStream=null;
        try {
            inputStream=multipartFile.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ossClient.putObject(ossConfig.getBucketName(),uploadImageUrl,inputStream,meta);



        //8.获取文件上传的返回地址
        return "http://"+ossConfig.getBucketName()+"."+ossConfig.getEndPoint()+"/"+uploadImageUrl;
    }


    //fileName 应该从数据库中 2021/4/22/XXXX.jpg
    @Override
    public boolean delete(String fileName) throws FileException {
        //1.获取ossClient
        //2.根据BuckName.fileName删除文件
        //删除目录中的文件，如果是最后一个张图片，则这个路径也会被删除
        try {
            String fileKey = Constants.OSS.ESTBASEURL + "/" + fileName;
            ossClient.deleteObject(ossConfig.getBucketName(), fileKey);

        }catch (Exception e){
            throw new FileException("文件删除失败");
        }
        return true;
    }

    @Override
    public void download(String fileName, HttpServletResponse response) throws IOException {
        //1.设置下载文件以附件的方式下载
        response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));

        //2.获取 bucket仓库，目标文件目录
           String bucket=ossConfig.getBucketName();
           String filehost=Constants.OSS.ESTBASEURL;
           //目录文件：yyyy/MM/dd 这些数据从数据库中获取数据库
           String filePath="2021/04/22";

           String fileKey=filehost+"/"+filePath+"/"+fileName;

        //3.获取ossObject对象，这个对象包含文件的存储空间名称，文件名，文件元信息  ossObject相当于文件对象
        OSSObject ossObject=ossClient.getObject(bucket,fileKey);

        //4.读取ossObject文件的内容


        try {
            //输入流
            InputStream inputStream =ossObject.getObjectContent();
            BufferedInputStream in=new BufferedInputStream(inputStream);
            ServletOutputStream  outputStream=response.getOutputStream();
            BufferedOutputStream out=new BufferedOutputStream(outputStream);

            byte[] buffer=new byte[1024];
            int len=0;
            while((len=in.read(buffer))!=-1){
                out.write(buffer,0,len);
            }

            if(out!=null){
                out.flush();
                out.close();
            }

            if(in!=null){
                in.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }
        //5.输出流输出文件信息
    }


}
